package com.example.common.view.vm

import android.util.Log
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.example.common.view.model.BaseRepository
import com.example.common.view.model.IResultData
import kotlinx.coroutines.CoroutineExceptionHandler
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.asCoroutineDispatcher
import kotlinx.coroutines.newFixedThreadPoolContext
import kotlinx.coroutines.newSingleThreadContext
import java.util.concurrent.Executors

/**
 * 基础ViewModel层
 *
 * ViewModel和AndroidViewmodel主要区别在于是否需要上下文对象
 *
 * ViewModel中业务:
 * 1.利用协程获取网络请求
 * 2.使用LiveData或StateFlow来管理数据
 * 3.通知View数据变化
 *
 * 注意:以前使用LiveData来缓存数据,存在数据倒灌问题,官方推荐Kotlin中使用Flow流,如果Java中官方推荐SingerLiveEvent或unPeekLiveData
 */

abstract class BaseViewModel<Repo:BaseRepository<*>, RD:IResultData> : ViewModel() {
    //定义LiveData缓存数据
    val mSuccessLiveData=MutableLiveData<RD>()
    val mErrorLiveData=MutableLiveData<String>()
    //协程异常处理
    //统一处理
    private val mExceptionHandler= CoroutineExceptionHandler{ctx,exception->
        Log.e("Coroutine Error","Error=====>${exception.message}")
       mErrorLiveData.postValue("ViewModel发生异常=====>${exception.message}")
    }
    //自定义协程作用域
    //SupervisorJob()创建独立的协程作用域,避免影响父协程和同级协程
    protected val mViewModelScope= CoroutineScope(Dispatchers.Main+ SupervisorJob()+ mExceptionHandler)
    //自定义协程调度器
    protected val mDispatcher= Executors.newFixedThreadPool(10).asCoroutineDispatcher()//使用Java创建线程池

    protected val mSingleDispatcher= newSingleThreadContext("SingleThreadDispatcher")//使用kotLin创建单线程池
    protected val mFixedThreadDispatcher= newFixedThreadPoolContext(16,"SingleThreadDispatcher")//使用kotLin创建固定数量线程池
}